package views;

import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import model.Problem;
import model.Solution;
import solver.CollaboratingSolvers;
import util.Chronograph;
import util.Importer;
import util.SolutionImporter;

public class MachineReassignmentJuneV1 {
	private static Logger log = LoggerFactory
			.getLogger(MachineReassignmentJuneV1.class);

	static final String TEAM_ID = "S5";

	static {
		String os_name = System.getProperty("os.name").toLowerCase();
		String os_arch = System.getProperty("os.arch").toLowerCase();
		if ((os_name.indexOf("win") >= 0) && (os_arch.indexOf("64") > 0))
			System.loadLibrary("libwin64//jnilinearsolver");
		else
			System.loadLibrary("jnilinearsolver");
	}

	public static void main(String[] args) {
		Locale.setDefault(Locale.ENGLISH);
		int time_limit;
		String instance_filename;
		String original_solution_filename;
		String new_solution_filename;
		long seed;
		if ((args.length == 1) && (args[0].equalsIgnoreCase("-name"))) {
			System.out.printf("%s", TEAM_ID);
		} else if (args.length == 11) {
			time_limit = Integer.parseInt(getArgumentValue(args, "-t"));
			instance_filename = getArgumentValue(args, "-p");
			original_solution_filename = getArgumentValue(args, "-i");
			new_solution_filename = getArgumentValue(args, "-o");
			seed = Long.parseLong(getArgumentValue(args, "-s"));
			MachineReassignmentJuneV1 app = new MachineReassignmentJuneV1();
			app.launch(time_limit, instance_filename,
					original_solution_filename, new_solution_filename, seed,
					false);
		} else if (args.length == 13) {
			time_limit = Integer.parseInt(getArgumentValue(args, "-t"));
			instance_filename = getArgumentValue(args, "-p");
			original_solution_filename = getArgumentValue(args, "-i");
			new_solution_filename = getArgumentValue(args, "-o");
			seed = Long.parseLong(getArgumentValue(args, "-s"));
			MachineReassignmentJuneV1 app = new MachineReassignmentJuneV1();
			String c = getArgumentValue(args, "-c");
			boolean cost_in_name = c.equalsIgnoreCase("yes");
			app.launch(time_limit, instance_filename,
					original_solution_filename, new_solution_filename, seed,
					cost_in_name);
		} else {
			System.out.println("Usage:");
			System.out.println("java -jar MachineReassignmentJunev1 -name");
			System.out.println();
			System.out.println("java -jar MachineReassignmentJunev1 "
					+ "-t time_limit " + "-p instance_filename "
					+ "-i original_solution_filename "
					+ "-o new_solution_filename " + "-name " + "-s seed");
		}
	}

	private void launch(int time_limit, String instance_filename,
			String original_solution_filename, String new_solution_filename,
			long seed, boolean cost_in_name) {
		Chronograph chronos_test = new Chronograph();
		chronos_test.reset();
		// System.out.printf("\ntime_limit=%d\n", time_limit);
		// System.out.printf("problem_instance_filename=%s\n",
		// instance_filename);
		// System.out.printf("original_solution_filename=%s\n",
		// original_solution_filename);
		// System.out.printf("new_solution_filename=%s\n",
		// new_solution_filename);
		// System.out.printf("team=%s\n", TEAM_ID);
		// System.out.printf("seed=%d\n", seed);

		Chronograph chronos = new Chronograph();
		chronos.reset();
		Importer importer = new Importer(instance_filename);
		importer.readData();
		Problem problem = importer.getProblem();
		Problem.VERBOSE = false;
		// System.out.println(problem.getCondensedInfo());
		SolutionImporter solutionImporter = new SolutionImporter(problem);
		solutionImporter.setSolutionFileName(original_solution_filename);
		Solution initial_solution = solutionImporter.readData();

		Problem.RANDOM_SEED = seed;
		boolean useGRB = false;
		CollaboratingSolvers solver = new CollaboratingSolvers(problem,
				initial_solution);

		chronos.lap();
		int time_passed_sec = chronos.getElapsedTimeInSeconds();
		solver.setSaved_solution_filename(new_solution_filename);
		solver.solveWithTimeLimit(time_limit - time_passed_sec);

		solver.getEnv().getFullValidator().computeCost();
		solver.getEnv().getFullValidator().printCostAnalysis();
		boolean f = solver.getEnv().getFullValidator().isFeasible();
		chronos_test.lap();
		log.info(String.format("Using %s, time passed=%d cost=%,d %s\n",
				useGRB ? "GUROBI" : "CBC", chronos_test
						.getElapsedTimeInSeconds(), solver.getEnv()
						.getFullValidator().getNewSolutionCost(), f ? ":)"
						: ":("));
		solver.saveSolution(solver.getEnv().getFullValidator()
				.getNewSolutionCost(), chronos_test.getElapsedTimeInSeconds(),
				cost_in_name);
	}

	private static String getArgumentValue(String[] args, String key) {
		if (key.equalsIgnoreCase("-name"))
			return TEAM_ID;
		int pos = 0;
		for (int i = 0; i < args.length; i++) {
			if (args[i].equalsIgnoreCase(key)) {
				pos = i;
			}
		}
		return args[pos + 1];
	}

}
